#ifndef FIFO_H_
#define FIFO_H_

#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sched.h>

#include <Constantes.h>
#include <MemoriaCompartida.h>
#include <Semaforo.h>
#include <ExitHandler.h>

class Fifo {
public:
	Fifo( const char projectId );
	Fifo(const std::string& nombre, const int modoCreacion, const char projectId, const bool protectAccess);
	virtual ~Fifo();
	virtual void abrir() = 0;
	void crear(const std::string& nombre, const int modoCreacion, const bool protectAccess);
	void cerrar();
	void destruir();
	
	void lock();
	void unlock();
	
	bool mustExit() const;
	void setExitHandler(ExitHandler* handler);
	
	bool hasContent() const;
	
	struct TControlFifo {
		unsigned int cantEscritores;
		unsigned int cantLectores;
		unsigned int bytesContenidos;
		bool cerrarRecepcion;
	};
	
protected:
	std::string m_Nombre;
	int fd;
	
	void cerrarRecepcion();
	
	void decrementarBytesContenidos(ssize_t cantBytes);
	void incrementarBytesContenidos(ssize_t cantBytes);
	
private:
	MemoriaCompartida<TControlFifo> m_ControlFifo;
	const char m_ProjectId;
	std::string m_NombreLock;
	ExitHandler* m_ExitHandler;
	Semaforo m_Semaforo;
	pid_t m_CreatorPid;
	bool m_ProtectAccess;
	
	void eliminar();
};

#endif /* FIFO_H_ */
